<?php
namespace App\Models;

use Illuminate\Support\Facades\DB;

/**
 * Created by PhpStorm.
 * User: zxj
 * Date: 2017/9/4
 * Time: 12:53
 */
class Trade extends BaseModel
{

    protected $table = "trade";

    public $timestamps = false;

    public function getOne($where, $fileds = '*', $order = '')
    {
        if (!$order) {
            $order = ['bank_id' => 'desc'];
        }
        return $this->multiSelect($fileds)->multiWhere($where)->multiOrder($order)->first();
    }

    /**
     * 按条件查询全部数据,根据配置显示条数显示
     */
    public function getList(array $where = [], $fields = '*', $order = '', $pageSize = '')
    {
        if ($pageSize) {
            return $this->multiSelect($fields)->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        } else {
            return $this->multiSelect($fields)->multiWhere($where)->multiOrder($order)->get();
        }
    }


    /**
     * 按条件查询全部数据,根据配置显示条数显示
     */
    public function getOrderCurrencyMemberList(array $where = [], $fields = '*', $order = '', $pageSize = '')
    {
        if ($pageSize) {
            return $this->with('currency')->with('member')->multiSelect($fields)->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        } else {
            return $this->with('currency')->with('member')->multiSelect($fields)->multiWhere($where)->multiOrder($order)->get();
        }
    }

    public function currency()
    {
        return $this->belongsTo('App\Models\Currency', 'currency_id', 'currency_id');
    }

    public function member()
    {
        return $this->belongsTo('App\Models\Member', 'member_id', 'member_id');
    }

    /**
     *插入数据
     */
    public function add($data)
    {
        return $this->_add($data);
    }


    /***
     * @param array $id
     * @param array $data
     * 更新数据
     */
    public function up($where, $data)
    {
        return $this->_updata($where, $data);
    }


    /**
     * @param $id
     * 删除数据
     */
    public function del($where)
    {
        return $this->_del($where);
    }

    public function count($where=[], $field='')
    {
        return $this->multiWhere($where)->count($field);
    }

    public function sum($where=[], $field)
    {
        return $this->multiWhere($where)->sum($field);
    }

    public function max($where=[], $field)
    {
        return $this->multiWhere($where)->max($field);
    }

    public function min($where=[], $field)
    {
        return $this->multiWhere($where)->min($field);
    }

    /**
     *
     * 银行卡会员列表
     *
     */
    public function getWebsiteBankList()
    {

        $where = [];
        $order['bank_id'] = 'desc';
        $rows = $this->getList($where, '*', $order, 10);
        if ($rows) {
            $rows = $rows->toArray();
            $rows['pageNoList'] = $this->getPageNoList($rows['last_page'], request('page', 1), 3);
            return $rows;
        }

    }

    /**
     *
     * 添加银行卡
     *
     */
    public function addBank($request)
    {

        $data['bank_name'] = trim($request['bank_name']);
        $data['bank_adddress'] = trim($request['bank_adddress']);
        $data['bank_no'] = trim($request['bank_no']);
        $data['status'] = 1;


        $message = $this->checkFileds($data);     //验证字段是否为空,如果有返回值则验证不通过
        if ($message) {
            return $message;
        }

        $did = $this->add($data);
        if (!$did) {
            $res = "服务器繁忙,请稍后重试";
            return $res;
        }
        $res = "添加用户成功";
        return $res;

    }

    /**
     * @param $data
     * @return string
     * 修改银行卡
     */
    public function saveBank($request)
    {
        $data['bank_name'] = trim($request['bank_name']);
        $data['bank_adddress'] = trim($request['bank_adddress']);
        $data['bank_no'] = trim($request['bank_no']);
        $data['status'] = trim($request['status']);


        $message = $this->checkFileds($data);     //验证字段是否为空,如果有返回值则验证不通过
        if ($message) {
            return $message;
        }

        $where['bank_id'] = $request['bank_id'];
        $did = $this->up($where, $data);
        if (!$did) {
            $res = "服务器繁忙,请稍后重试";
            return $res;
        }
        $res = "修改银行卡成功";
        return $res;

    }

    /**
     *
     * ajax删除银行卡
     *
     */
    public function delBank($request)
    {

        if (!isset($request['id'])) {
            $data['status'] = 0;
            $data['msg'] = '传入参数有误！';
            return $data;
        }
        $where['bank_id'] = $request['id'];
        $did = $this->del($where);
        if ($did) {
            $data['status'] = 1;
            $data['msg'] = '删除成功！';
        } else {
            $data['status'] = 0;
            $data['msg'] = '删除失败！';
        }

        return $data;
    }

    /**
     * @param $data
     * @return string
     * 查询单个银行卡
     */
    public function getOneBank($request)
    {
        $where['bank_id'] = $request['bank_id'];
        $data = $this->getOne($where);
        return $data;
    }


    //验证表单字段是否为空
    public function checkFileds($data)
    {

        if (!$data['bank_name']) {
            return '收款人不能为空';
        }
        if (!$data['bank_adddress']) {
            return '开户行不能为空';
        }
        if (!$data['bank_no']) {
            return '账号不能为空';
        }

    }


    function getPageNoList($totalPage, $pageNo, $pageSize)
    {
        $disPageList = 0;//定义最大链接显示数额
        $disPageList = $pageNo + $pageSize - 1;//最大链接显示数额赋值，公式为"当前页数 + 最大链接显示数额 -1"
        //前页面导航页数
        $pageNoList = array();
        //循环显示出当前页面导航页数
        if ($disPageList <= $totalPage) {
            for ($i = $pageNo; $i <= $disPageList; $i++) {
                $pageNoList[] = $i;
            }
        } else {
            if ($totalPage < $pageSize) {
                for ($i = 1; $i <= $totalPage; $i++) {
                    $pageNoList[] = $i;
                }
            } else {
                $start = $totalPage - $pageSize + 1;
                for ($i = $start; $i <= $totalPage; $i++) {
                    $pageNoList[] = $i;
                }
            }
        }
        return $pageNoList;
    }

    //挂单记录:Trade表+currency表+member表带分页
    public function getTradeCurrencyMemberListFenye($request)
    {
        $where = [];
        $type = isset($request['type']) ? trim($request['type']) : ''; //sell卖出,buy买入
        $currency_id = isset($request['currency_id']) ? trim($request['currency_id']) : '';    //币种类型
        $email = isset($request['email']) ? trim($request['email']) : '';    //购买人email
        if (!empty($currency_id)) {
            $where['currency_id'] = $currency_id;
        }
        if (!empty($type)) {
            $where['type'] = $type;
        }
        if (!empty($email)) {
            $member_model = new Member();
            $memberinfo = $member_model->getOne(['email' => $email]);
            //dd($memberinfo);
            $where['member_id'] = $memberinfo['member_id'];

        }

        $order['add_time'] = 'desc';
        $rows = $this->getOrderCurrencyMemberList($where, '*', $order, 10);

        if ($rows) {
            $rows = $rows->toArray();
            $rows['pageNoList'] = $this->getPageNoList($rows['last_page'], request('page', 1), 5);
        }
        return $rows;
    }


    /********    前台    *********/


    /**
     * 我的成交
     */
    public function index($request)
    {
        //获取主币种
        $currency = $this->getCurrencyByCurrencyId();
        $currencytype = $request['currency'];
        if (!empty($currencytype)) {
            $where['currency_id'] = $currencytype;
        }
        $where['member_id'] = session('USER_KEY_ID');

        // 进行分页数据查询 注意limit方法的参数要使用Page类的属性
        $list = $this->getList($where)->toArray();
        return [$currency,$list];
    }


    //买入
    public function buy($request)
    {
        if (!session('USER_KEY_ID')) {
            $data['status'] = 0;
            $data['info'] = '请先登录再进行此操作!';
            return $data;
        }
        //交易时间段限制
        $time = strtotime(date('Y-m-d'));
        $config = (new Config())->getCache();
        $start_time = $time + $config['jiaoyi_start_hour'] * 3600 + $config['jiaoyi_start_minute'] * 60;
        $over_time = $time + $config['jiaoyi_over_hour'] * 3600 + $config['jiaoyi_over_minute'] * 60;
        if (time() < $start_time || time() > $over_time) {
            $data['status'] = -10;
            $data['info'] = '交易未开启，请在交易时间内进行交易!';
            return $data;
        }
        $buyprice = floatval($request['buyprice']);
        $buynum = intval($request['buynum']);
        $buypwd = $request['buypwd'];
        $buycurrency_id = intval($request['currency_id']);
        //获取币的相关信息
        $currency = $this->getCurrencyByCurrencyId($buycurrency_id);
        if ($currency['is_lock']) {
            $data['status'] = -5;
            $data['info'] = '该币种暂时不允许交易!';
            return $data;
        }

        if (!is_numeric($buyprice) || !is_numeric($buynum)) {
            $data['status'] = 0;
            $data['info'] = '您的挂单价格或数量有误,请修改!';
            return $data;
        }
        //涨停价格限制
        if ($currency['price_down'] > 0 && $buyprice < $currency['price_down']) {
            $msg['status'] = -9;
            $msg['info'] = '交易价格超出了跌停价格限制!';
            return $msg;
        }

        //涨停价格限制
        if (($currency['price_up'] > 0) && ($buyprice > $currency['price_up'])) {
            $msg['status'] = -7;
            $msg['info'] = '交易价格超出了涨停价格限制!';
            return $msg;
        }

        if ($buyprice * $buynum < 1) {
            $data['status'] = 0;
            $data['info'] = '不能委托低于1元的订单!';
            return $data;
        }
        if (!is_int($buynum)) {
            $data['status'] = -1;
            $data['info'] = '交易数量必须是整数!';
            return $data;
        }
        if ($buynum < 0) {
            $data['status'] = -2;
            $data['info'] = '交易数量必须是正数';
            return $data;
        }
        $member = $this->mb(session('USER_KEY_ID'));
        if (md5($buypwd) != $member['pwdtrade']) {
            $data['status'] = -3;
            $data['info'] = '交易密码不正确!';
            return $data;
        }
        if ($this->checkUserMoney($buynum, $buyprice, 'buy', $currency)) {
            $data['status'] = -4;
            $data['info'] = '您账户余额不足!';
            return $data;
        }

        //开启事物
        $this->start();
        try {
            //计算买入需要的金额
            $trade_money = $buynum * $buyprice;//*(1+($currency['currency_buy_fee']/100));
            //操作账户
            $r[] = $this->setUserMoney(session('USER_KEY_ID'), $currency['trade_currency_id'], $trade_money, 'dec', 'num');
            $r[] = $this->setUserMoney(session('USER_KEY_ID'), $currency['trade_currency_id'], $trade_money, 'inc', 'forzen_num');
            //挂单流程
            $r[] = $this->guadan($buynum, $buyprice, 'buy', $currency);
            //交易流程
            $r1[] = $this->trade($currency['currency_id'], 'buy', $buynum, $buyprice);
            foreach ($r1 as $v) {
                $r[] = $v;
            }
                $this->commit();
                $msg['status'] = 1;
                $msg['info'] = '操作成功!';
                return $msg;
        }catch (\Exception $e) {
            $this->rollback();
            $msg['status'] = -7;
            $msg['info'] = '操作失败!';
            return $msg;
        }

    }

    /*卖出
     *
     * 1.是否登录
     * 1.5 是否开启交易
     * 2.准备数据
     * 3.判断数据
     * 4.检查账户
     * 5.操作个人账户
     * 6.写入数据库
     *
     *
     *
     */

    public function sell($request)
    {
        if (!session('USER_KEY_ID')) {
            $msg['status'] = 0;
            $msg['info'] = '请先登录再进行此操作!';
            return $msg;
        }
        //交易时间段限制
        $time = strtotime(date('Y-m-d'));
        $config = (new Config())->getCache();
        $start_time = $time + $config['jiaoyi_start_hour'] * 3600 + $config['jiaoyi_start_minute'] * 60;
        $over_time = $time + $config['jiaoyi_over_hour'] * 3600 + $config['jiaoyi_over_minute'] * 60;
        if (time() < $start_time || time() > $over_time) {
            $msg['status'] = -10;
            $msg['info'] = '交易未开启，请在交易时间内进行交易!';
            return $msg;
        }
        $sellprice = $request['sellprice'];
        $sellnum = $request['sellnum'];
        $sellpwd = $request['sellpwd'];
        $currency_id = $request['currency_id'];
        //获取币种信息
        $currency = $this->getCurrencyByCurrencyId($currency_id);
        //检查是否开启交易
        if ($currency['is_lock']) {
            $msg['status'] = -2;
            $msg['info'] = '该币种暂时不能交易!';
            return $msg;
        }

        if (empty($sellprice) || empty($sellnum)) {
            $msg['status'] = -3;
            $msg['info'] = '卖出价格或在数量不能为空!';
            return $msg;
        }

        if ($sellnum * $sellprice < 1) {
            $data['status'] = 0;
            $data['info'] = '不能委托低于1元的订单!';
            return $data;
        }

        if (empty($sellpwd)) {
            $msg['status'] = -4;
            $msg['info'] = '交易密码不能为空!';
            return $msg;
        }
        $member = $this->mb(session('USER_KEY_ID'));
        if ($member['pwdtrade'] != md5($sellpwd)) {
            $msg['status'] = -5;
            $msg['info'] = '交易密码不正确!';
            return $msg;
        }
        //涨停价格限制
        if ($currency['price_down'] > 0 && $sellprice < $currency['price_down']) {
            $msg['status'] = -9;
            $msg['info'] = '交易价格超出了跌停价格限制!';
            return $msg;
        }

        //涨停价格限制
        if ($currency['price_up'] > 0 && $sellprice > $currency['price_up']) {
            $msg['status'] = -7;
            $msg['info'] = '交易价格超出了涨停价格限制!';
            return $msg;
        }
        //检查账户是否有钱
        if ($this->checkUserMoney($sellnum, $sellprice, 'sell', $currency)) {
            $msg['status'] = -6;
            $msg['info'] = '您的账户余额不足!';
            return $msg;
        }
        //减可用钱 加冻结钱
        $this->start();
        try
        {
            $r[] = $this->setUserMoney(session('USER_KEY_ID'), $currency['currency_id'], $sellnum, 'dec', 'num');
            $r[] = $this->setUserMoney(session('USER_KEY_ID'), $currency['currency_id'], $sellnum, 'inc', 'forzen_num');
            //写入数据库
            $r[] = $this->guadan($sellnum, $sellprice, 'sell', $currency);
            //成交
            $r[] = $this->trade($currency['currency_id'], 'sell', $sellnum, $sellprice);
                $this->commit();
                $msg['status'] = 1;
                $msg['info'] = '操作成功!';
                return $msg;
        }catch (\Exception $e) {
            $this->rollback();
            $msg['status'] = -7;
            $msg['info'] = '操作失败!';
            return $msg;
        }

    }


    /**
     *
     * @param int $currency_id 币种id
     * @return array 币种结果集
     */
    public function getCurrencyByCurrencyId($currency_id = 0)
    {
        if (empty($currency_id)) {
            $where[] = array('currency_id', '>', $currency_id);
        } else {
            $where['currency_id'] = $currency_id;
        }
        //获取交易币种信息
        $list = Currency::select('currency_id', 'price_up', 'price_down', 'currency_buy_fee', 'currency_sell_fee', 'trade_currency_id', 'is_lock', 'rpc_url', 'rpc_pwd', 'rpc_user', 'port_number', 'currency_all_tibi')->where($where)->get();
        if (!empty($currency_id)) {
            return $list[0];
        } else {
            return $list;
        }
    }

    public function mb($field)
    {
        $member = Member::select('*', DB::raw('(rmb+forzen_rmb) as count'))->where('member_id', $field)->first();
        if (!empty($member)) {
            return $member;
        } else {
            return '';
        }

    }

    /**
     * 获取当前币种的信息
     * @param int $id 币种id
     * @return 24H成交量 24H_done_num  24H成交额 24H_done_money 24H涨跌 24H_change 7D涨跌  7D_change
     * @return 最新价格 new_price 买一价 buy_one_price 卖一价 sell_one_price 最高价 max_price 最低价 min_price
     */

    public function getCurrencyMessageById($id)
    {
        $where['currency_id'] = $id;
        $time = time();
        //一天前的时间
        $old_time = strtotime(date('Y-m-d', $time));
        //最新价格
        $order['add_time'] = 'desc';
        $rs = $this->getOne($where, '*', $order);
        $data['new_price'] = $rs['price'];
        //判断价格是升是降
        $where['add_time'] = ['<', $old_time];
        $re = $this->getOne($where, '*', $order);
        if ($re['price'] > $rs['price']) {
            //说明价格下降
            $data['new_price_status'] = 0;
        } else {
            $data['new_price_status'] = 1;
        }
        //24H涨跌
        $where['add_time'] = ['<', $time - 60 * 60 * 24];
        $re = $this->getOne($where, '*', $order);
        if ($re['price'] != 0) {
            $data['24H_change'] = sprintf("%.2f", ($rs['price'] - $re['price']) / $re['price'] * 100);
            if ($data['24H_change'] == 0) {
                $data['24H_change'] = 100;
            }
        } else {
            $data['24H_change'] = 100;
        }
        //7D涨跌
        $where['add_time'] = ['<', $time - 60 * 60 * 24 * 7];
        $re = $this->getOne($where, '*', $order);
        if ($re['price'] != 0) {
            $data['7D_change'] = sprintf("%.2f", ($rs['price'] - $re['price']) / $re['price'] * 100);
            if ($data['7D_change'] == 0) {
                $data['7D_change'] = 100;
            }
        } else {
            $data['7D_change'] = 100;
        }
        //24H成交量
        $where['add_time'] = ['>', $time - 60 * 60 * 24];
        $rs = $this->sum($where, 'num');
        $data['24H_done_num'] = $rs;
        //24H成交额
        $where['add_time'] = ['>', $time - 60 * 60 * 24];
        $rs=$this->multiSelect('sum(num * price) as total_money')->multiWhere($where)->first();
        $data['24H_done_money'] = $rs['total_money'];
        //最低价
        $data['min_price'] = $this->getminPriceTrade($id);
        //最高价
        $data['max_price'] = $this->getmaxPriceTrade($id);
        //买一价
        $data['buy_one_price'] = $this->getOneOrdersByPrice($id, 'buy');
        //卖一价
        $data['sell_one_price'] = $this->getOneOrdersByPrice($id, 'sell');
        //返回
        return $data;
    }

    /**
     * 获取一个挂单记录价格 买一 卖一
     * @param unknown $currencyid
     * @param unknown $type
     * @param unknown $order
     */
    protected function getOneOrdersByPrice($currencyid, $type)
    {
        $where['currency_id'] = $currencyid;
        $where['type'] = $type;
        $where['status'] = ['in', [0, 1]];
        $order = 'desc';
        if ($type == 'sell') {
            $order = 'asc';
        }
        $orderModel = new Orders();
        $orderInfo = $orderModel->getOne($where, 'price', ['price' => $order]);
        return $orderInfo['price'];
    }

    /**
     * 返回最高价
     * @param int $currency_id 币种ID
     */
    protected function getMaxPriceTrade($currency_id)
    {
        $trade = $this->getTradeByPrice($currency_id, 'desc');
        return $trade['price'];
    }

    /**
     * 返回最低价
     * @param int $currency_id 币种ID
     */
    protected function getminPriceTrade($currency_id)
    {
        $trade = $this->getTradeByPrice($currency_id, 'asc');
        return $trade['price'];
    }

    /**
     * 指定价格一个成交记录
     * @param int $currency_id 币种ID
     * @param char $order 排序
     */
    private function getTradeByPrice($currency_id, $order)
    {
        return $this->getOne(['currency_id' => $currency_id], 'price', ['price' => $order]);
    }

    //获取K线
    public function getKline($base_time, $currency_id)
    {
        $time = time() - $base_time * 60 * 60;
        for ($i = 0; $i < 60; $i++) {
            $start = $time + $base_time * 60 * $i;
            $end = $start + $base_time * 60;

            //时间
            $item[$i][] = $start * 1000 + 8 * 3600 * 1000;
            $where['currency_id'] = $currency_id;
            $where['type'] = 'buy';
            $where['add_time'] = ['between',[$start, $end]];
            //交易量
            $num =$this->sum($where,'num');
            $item[$i][] = !empty($num) ? floatval($num) : 0;
            //开盘
            $where_price['currency_id'] = $currency_id;
            $where_price['type'] = 'buy';
            $where_price['add_time'] = ['<=',$end];
            $orderBy['add_time'] = 'desc';
            $order_k = $this->getOne($where_price,'price',$orderBy);
            $item[$i][] = !empty($order_k['price']) ? floatval($order_k['price']) : 0;
            //最高
            $max =$this->max($where,'price');
            $max = !empty($max) ? floatval($max) : $order_k['price'];
            $max = !empty($max) ? $max : 0;
            $item[$i][] = $max;
            //最低
            $min =$this->min($where,'price');
            $min = !empty($min) ? floatval($min) : $order_k['price'];
            $item[$i][] = !empty($min) ? $min : 0;
            //收盘
            $orderBy['add_time'] = 'asc';
            $order_s = $this->getOne($where,'price',$orderBy);
            $order_s = !empty($order_s['price']) ? floatval($order_s['price']) : $order_k['price'];
            $item[$i][] = !empty($order_s) ? $order_s : 0;
        }
        // $item=json_encode($item,true);
        return $item;
    }


    /**
     *
     * @param int  $num 数量
     * @param float $price 价格
     * @param char $type 买buy 卖sell
     * @param $currency_id 交易币种
     */
    private function  checkUserMoney($num,$price,$type,$currency){
        //获取交易币种信息
        if ($type == 'buy'){
            $trade_money = $num*$price*(1 + $currency['currency_buy_fee']/100);
            $currency_id = $currency['trade_currency_id'];
        }else {
            $trade_money = $num;
            $currency_id = $currency['currency_id'];
        }
        //和自己的账户做对比 获取账户信息
        $money = $this->getUserMoney($currency_id, 'num');
        if ($money < $trade_money) {
            return true;
        }else{
            return false;
        }
    }

    /**
     *  获取当前登陆账号指定币种的金额
     * @param int $currency_id 币种ID
     * @param char $field  num  forzen_num
     * @return array 当前登陆人账号信息
     */
    protected  function getUserMoney($currency_id,$field){

        if (empty($currency_id)){
            switch ($field){
                case 'num':$field='rmb';break;
                case 'forzen_num':$field='forzen_rmb';break;
                default:$field='rmb';
            }
            $where['member_id'] = session('USER_KEY_ID');
            $member = (new Member())->getOne($where,$field);
        }else {
            $where['currency_id'] = $currency_id;
            $currency_user = (new CurrencyUser())->getOne($where,"*");
        }
        return  isset($member[$field])? $member[$field]:$currency_user[$field];
    }


    /**
     * 设置账户资金
     * @param int $currency_id  币种ID
     * @param int $num 交易数量
     * @param char $inc_dec  setDec setInc 是加钱还是减去
     * @param char forzen_num num
     */
    protected   function setUserMoney($member_id,$currency_id,$num,$inc_dec,$field){
        $inc_dec = strtolower($inc_dec) ;
        $field = strtolower($field) ;
        //允许传入的字段
        if (!in_array($field, array('num','forzen_num'))){
            return false;
        }
        //如果是RMB
        if ($currency_id == 0){
            //修正字段
            switch ($field){
                case 'forzen_num': $field='forzen_rmb';break;
                case 'num': $field='rmb';break;
            }
            $member = new Member();
            switch ($inc_dec){
                case 'inc':
                    $re = $member->getOne(['member_id'=>$member_id],$field);
                    $re = $re[$field] + $num;
                    $msg = $member->up(['member_id' => $member_id],[$field => $re]);
//                    $msg= M('Member')->where("member_id=$member_id ")->setInc($field,$num);
                    break;
                case 'dec':
                    $re = $member->getOne(['member_id'=>$member_id],$field);
                    $re = $re[$field] - $num;
                    $msg = $member->up(['member_id' => $member_id],[$field => $re]);
//                    $msg= M('Member')->where("member_id=$member_id")->setDec($field,$num);
                    break;
                default:return false;
            }
            return $msg;
        }else{
            $currencyUser = new CurrencyUser();
            switch ($inc_dec){
                case 'inc':
                    $re = $currencyUser->getOne(['member_id' => $member_id,'currency_id' => $currency_id],$field);
                    $re = $re[$field] + $num;
                    $msg = $currencyUser->up(['member_id' => $member_id,'currency_id' => $currency_id],[$field => $re]);
//                    $msg= M('Currency_user')->where("member_id=$member_id and currency_id=$currency_id")->setInc($field,$num);
                    break;
                case 'dec':
                    $re = $currencyUser->getOne(['member_id' => $member_id,'currency_id' => $currency_id],$field);
                    $re = $re[$field] - $num;
                    $msg = $currencyUser->up(['member_id' => $member_id,'currency_id' => $currency_id],[$field => $re]);
//                    $msg= M('Currency_user')->where("member_id=$member_id and currency_id=$currency_id")->setDec($field,$num);
                    break;
                default:return false;
            }
            return $msg;
        }
    }

    /**
     * 挂单
     * @param int  $num 数量
     * @param float $price 价格
     * @param char $type 买buy 卖sell
     * @param $currency_id 交易币种
     */
    private function guadan($num,$price,$type,$currency){
        //获取交易币种信息
        switch ($type){
            case 'buy':
                $fee = $currency['currency_buy_fee']/100;
                $currency_trade_id = $currency['trade_currency_id'];
                break;
            case 'sell':
                $fee = $currency['currency_sell_fee']/100;
                $currency_trade_id = $currency['trade_currency_id'];
                break;
        }
        $data = array (
            'member_id' => session('USER_KEY_ID'),
            'currency_id' => $currency['currency_id'],
            'currency_trade_id' => $currency['trade_currency_id'],
            'price' => $price,
            'num' => $num,
            'trade_num' => 0,
            'fee' => $fee,
            'type' => $type,
            'add_time' => time()
        );
        $order = new Orders();
        if ($msg = $order->add($data)){
            return $msg;
        }else {
            $msg = 0;
        }

    }

    private function trade($currencyId,$type,$num,$price){
        if ($type == 'buy'){
            $trade_type = 'sell';
        }else {
            $trade_type = 'buy';
        }
        $memberId = session('USER_KEY_ID');
        //获取操作人一个订单
        $orderModel = new Orders();
        $order = $orderModel->getFirstOrdersByMember($memberId,$type ,$currencyId);
        //获取对应交易的一个订单
        $trade_order = $orderModel->getOneOrders($trade_type, $currencyId,$price);
        //如果没有相匹配的订单，直接返回
        if (empty($trade_order)) {
            $r[] = true;
            return $r;
        }
        //如果有就处理订单
        $trade_num = min($num,$trade_order['num']-$trade_order['trade_num']);
        //增加本订单的已经交易的数量
        $order_trade_num = $orderModel->getOne(['orders_id'=>$order['orders_id']],'trade_num');
        $order_trade_num = $order_trade_num['trade_num'] + $trade_num;
        $data['trade_num'] = $order_trade_num;
        $data['trade_time'] = time();
        $r[] = $orderModel->up(['orders_id'=>$order['orders_id']],$data);
        //增加trade订单的已经交易的数量
        $order_trade_num2 = $orderModel->getOne(['orders_id'=>$trade_order['orders_id']],'trade_num');
        $order_trade_num2 = $order_trade_num2['trade_num'] + $trade_num;
        $res['trade_num'] = $order_trade_num2;
        $res['trade_time'] = time();
        $r[] = $orderModel->up(['orders_id'=>$trade_order['orders_id']],$res);

        //更新一下订单状态
        $where['trade_num'] = ['>',0];
        $where['status'] = 0;
        $r[] = $orderModel->up($where,['status'=>1]);
        $sql = "UPDATE xnb_orders a JOIN xnb_orders b ON a.num = b.trade_num SET b.status = 2";
        $r[] = DB::select($sql);
        //处理资金
        switch ($type){

            case 'buy':
                $trade_price = min($order['price'],$trade_order['price']);
                $trade_order_money = $trade_num * $trade_price * (1-($trade_order['fee']/100));
                $order_money = $trade_num * $trade_price;//*(1+$order['fee']);
                $r[]= $this->setUserMoney(session('USER_KEY_ID'),$order['currency_id'], $trade_num*(1-($order['fee']/100)), 'inc', 'num');
                $r[] = $this->setUserMoney(session('USER_KEY_ID'),$order['currency_trade_id'], $order_money, 'dec', 'forzen_num');
                $r[] = $this->setUserMoney(session('USER_KEY_ID'),$trade_order['currency_id'],  $trade_num, 'dec', 'forzen_num');
                $r[] = $this->setUserMoney(session('USER_KEY_ID'),$trade_order['currency_trade_id'], $trade_order_money, 'inc', 'num');
                //返还多扣除的部分
                $r[] = $this->setUserMoney(session('USER_KEY_ID'),$order['currency_trade_id'], $trade_num* ($order['price']-$trade_price), 'inc', 'num');
                $r[] = $this->setUserMoney(session('USER_KEY_ID'),$order['currency_trade_id'], $trade_num * ($order['price']-$trade_price), 'dec', 'forzen_num');

                //手续费
                $r[] = $this->addFinance($order['member_id'], 11, '交易手续费',$trade_num * ($order['fee']/100), 2, $order['currency_id']);
                $r[] = $this->addFinance($trade_order['member_id'], 11, '交易手续费',$trade_num*$trade_price*($trade_order['fee']/100), 2, $order['currency_trade_id']);
                break;
            case 'sell':

                $trade_price = max($order['price'],$trade_order['price']);
                $order_money = $trade_num * $trade_price * (1-($order['fee']/100));
                $trade_order_money = $trade_num*$trade_price;//*(1+$trade_order['fee']);

                $r[] = $this ->setUserMoney(session('USER_KEY_ID'),$order['currency_id'], $trade_num, 'dec', 'forzen_num');
                $r[] = $this->setUserMoney(session('USER_KEY_ID'),$order['currency_trade_id'], $order_money, 'inc', 'num');

                $r[] = $this->setUserMoney($trade_order['member_id'],$trade_order['currency_id'], $trade_num*(1-($order['fee']/100)), 'inc', 'num');
                $r[] = $this->setUserMoney($trade_order['member_id'],$trade_order['currency_trade_id'],$trade_order_money, 'dec', 'forzen_num');
                //手续费
                $r[] = $this->addFinance($order['member_id'], 11, '交易手续费',$trade_num*$trade_price*($order['fee']/100), 2, $order['currency_trade_id']);
                $r[] = $this->addFinance($trade_order['member_id'], 11, '交易手续费',$trade_num*($trade_order['fee']/100), 2, $order['currency_id']);
                break;
        }
        //修正最终成交的价格
        $sql2 = "UPDATE xnb_orders a JOIN xnb_orders b ON a.num = b.trade_num SET b.price = ".$trade_price." WHERE b.orders_id = ".$order['orders_id']."";
        $r[] = DB::select($sql2);
        $sql3 = "UPDATE xnb_orders a JOIN xnb_orders b ON a.num = b.trade_num SET b.price = ".$trade_price." WHERE b.orders_id = ".$trade_order['orders_id']."";
        $r[] = DB::select($sql3);
//        $r[]=M('Orders')->where("num=trade_num and orders_id={$order['orders_id']}")->setField('price',$trade_price);
//        $r[]=M('Orders')->where("num=trade_num and orders_id={$trade_order['orders_id']}")->setField('price',$trade_price);
        //写入成交表
        $r[] = $this->addTrade($order['member_id'], $order['currency_id'], $order['currency_trade_id'],$trade_price, $trade_num, $order['type'],($order['fee']/100));
        $r[] = $this->addTrade($trade_order['member_id'], $trade_order['currency_id'], $trade_order['currency_trade_id'], $trade_price, $trade_num, $trade_order['type'],($order['fee']/100));
        $num = $num- $trade_num;
        if ($num > 0){
            //递归
            $r[]= $this->trade($currencyId, $type, $num, $price);
        }
        return $r;

    }


    /**
     * 添加财务日志方法
     * @param unknown $member_id
     * @param unknown $type
     * @param unknown $content
     * @param unknown $money
     * @param unknown $money_type  收入=1/支出=2
     * @param unknown $currency_id  币种id 0是rmb
     * @return
     */
    public function addFinance($member_id,$type,$content,$money,$money_type,$currency_id){
        $data['member_id'] = $member_id;
        $data['type'] = $type;
        $data['content'] = $content;
        $data['money_type'] = $money_type;
        $data['money'] = $money;
        $data['add_time'] = time();
        $data['currency_id'] = $currency_id;
        $data['ip'] = get_ip();
        $list = (new Finance())->add($data);
        if($list){
//            return $list;
            return true ;
        }else{
            return false;
        }
    }

    /**
     * 增加交易记录
     * @param unknown $member_id
     * @param unknown $currency_id
     * @param unknown $currency_trade_id
     * @param unknown $price
     * @param unknown $num
     * @param unknown $type
     * @return boolean
     */
    private function  addTrade($member_id,$currency_id,$currency_trade_id,$price,$num,$type,$fee){
        switch ($type){
            case 'buy':$fee = $num*$fee;break;
            case 'sell':$fee = $price*$num*$fee;break;
            default:$fee = 0;
        }
        $this->dividend($price*$num,$member_id);
        $data = array(
            'member_id' => $member_id,
            'currency_id' => $currency_id,
            'currency_trade_id' => $currency_trade_id,
            'price' => $price,
            'num' => $num,
            'fee' => $fee,
            'money' => $price*$num,
            'type' => $type,
        );
        if ($this->add($data)){
                return true;
        }else {
            return false;
        }
    }

    /**
     * 分红奖励全部
     *@param $money 传入交易金额
     *@param $member_id 用户id 不传自动处理登录用户
     */
    protected function dividend($money,$member_id=''){
        if (empty($member_id)) {
            $userid = session('USER_KEY_ID');
        }
        $num = $this->findDividendMinNum();
        if (!$num) {
            return ;
        }
        //max是还可以获得多少个分红股
        $max = $this->getUserAddDividendPower($member_id,$num);
        if (!$max) {
            return ;
        }
        //增加用户分红业绩
        if (!$this->addUserDividendNum($money,$member_id,$max,$num)) {
            return;
        }
        $this->addDividend($member_id,$num,$max);

    }

    /**
     * 获取触发分红业绩
     * return 触发分红业绩后缀
     */
    private function findDividendMinNum(){

        $dividend_all = $this->dividendConfig();
        $dividend_id = $dividend_all['dividend_id'];
        $num1 = $dividend_all['num1'];
        $num2 = $dividend_all['num2'];
        $num3 = $dividend_all['num3'];
        $num4 = $dividend_all['num4'];
        $num = (new Currency())->getOne(['currency_id'=>$dividend_id],'currency_all_num');
        if ($num['currency_all_num'] < $num1 * 10000) {
            return false;
        }
        if ($num['currency_all_num'] < $num2 * 10000) {
            return 1;
        }
        if ($num['currency_all_num'] < $num3 * 10000) {
            return 2;
        }
        if ($num['currency_all_num'] < $num4 * 10000) {
            return 3;
        }
        return false;
    }

    /**
     * 判断用户进入获得分红股数量是否超过当日上线
     * @param $money 用户表dividend_num代表分红业绩与金额等比例
     * @param
     * return 还可以获得的分红股数
     */
    private function getUserAddDividendPower($member_id,$num){
        $max = $this->dividendConfig['max'.$num];
        $today = strtotime(date('Y-m-d 0:0:0'));
        $where['type'] = 13;
        $where['add_time'] = ['>',$today];
        $where['member_id'] = $member_id;
        $count = (new Finance())->getList($where);
        $money = 0;
        if($count){
            foreach ($count as $k=>$v){
                $money += $v['money'];
            }
        }
        if ($money < $this->dividendConfig['max'.$num]) {
            return $this->dividendConfig['max'.$num] - $money;
        }
        return false;
    }

    /**
     * 增加用户分红业绩
     * @param $money 用户表dividend_num代表分红业绩与金额等比例
     * @param
     * return 成功失败
     */
    private function addUserDividendNum($money,$member_id,$max){
        if ($money > $max * $this->dividendConfig['money'.$max]) {
            $money = $max * $this->dividendConfig['money'.$max];
        }
        $member = new Member();
        $where['member_id'] = $member_id;
        $memberMoney = $member->getOne($where,$money);
        $memberMoney = $memberMoney['dividend_num'] + $money;
        $res = $member->up($where,['dividend_num' => $memberMoney]);
//        $res=M('Member')->where('member_id='.$member_id)->setInc('dividend_num',$money);

        if($res){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 触发分红业绩
     * $num 最少限制
     * $member_id 用户ID
     */
    private function addDividend($member_id,$num,$max){
        $memberModel = new Member();
        $currencyModel = new Currency();
        $member = $memberModel->getOne(['member_id'=>$member_id],'dividend_num,');
        $money = $this->dividendConfig['get'.$num];
        $n = floor($member['dividend_num']/$this->dividendConfig['money'.$num]);
        $n = min($n,$max);
        if($n){
            $dividend_num = $member['dividend_num'] + $this->dividendConfig['money'.$num]*$n;
            $memberModel->up(['member_id'=>$member_id],['dividend_num'=>$dividend_num]);
//            M('Member')->where('member_id='.$member_id)->setDec('dividend_num',$this->dividendConfig['money'.$num]*$n);
            $where['currency_id'] = $this->dividendConfig()['dividend_id'];
            $currency = $currencyModel->getOne($where,'currency_all_num');
            $currency_all_num = $currency['currency_all_num'] + $money*$n;
            $currencyModel->up($where,['currency_all_num'=>$currency_all_num]);
//            M('Currency')->where("currency_id=".$this->dividendConfig['dividend_id'])->setInc('currency_all_num',$money*$n);
            $this->setUserMoney($member_id, $this->dividendConfig()['dividend_id'],$money*$n, "inc",'num');
            $this->addFinance($member_id, 13, "获得分红股",$money*$n,1, $this->dividendConfig()['dividend_id']);

            return 2;
        }
        return 1;
    }

    public function dividendConfig()
    {
        $dividend = (new Dividend())->getlist();
        foreach ($dividend as $k=>$v){
            $dividendConfig[$v['name']] = $v['value'];
        }
        return $dividendConfig;
    }



    public function getTradeListWithCurrency(array $where, $fields = '*', array $order = [], $pageSize = 10, $pageLength = 5)
    {
        $rows = $this->multiSelect($fields)->with('currency')->withCertain('currency',['currency_id','currency_name'])->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        if ($rows) {
            $rows = $rows->toArray();
            $rows['pageNoList'] = $this->getPageNoList($rows['last_page'], request('page', 1), $pageLength);
        }
        return $rows;
    }
}